package com.zhentao.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhentao.dto.CouponDTO;
import com.zhentao.dto.UserCouponDTO;
import com.zhentao.mapper.CouponMapper;
import com.zhentao.mapper.UserCouponMapper;
import com.zhentao.pojo.Coupon;
import com.zhentao.pojo.UserCoupon;
import com.zhentao.service.CouponService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 优惠券Service实现类
 */
@Slf4j
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {

    @Autowired
    private UserCouponMapper userCouponMapper;

    @Override
    public List<CouponDTO> getAvailableCoupons() {
        QueryWrapper<Coupon> wrapper = new QueryWrapper<>();
        wrapper.eq("is_enabled", 1)
               .le("valid_start_time", LocalDateTime.now())  // 已经开始生效
               .ge("valid_end_time", LocalDateTime.now())    // 还未过期
               .gt("remaining_stock", 0);

        List<Coupon> coupons = list(wrapper);

        return coupons.stream().map(this::convertToDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean receiveCoupon(Long userId, Long couponId) {
        // 检查优惠券是否存在且可用
        Coupon coupon = getById(couponId);
        if (coupon == null || coupon.getIsEnabled() != 1) {
            log.warn("优惠券不存在或已禁用: {}", couponId);
            return false;
        }

        // 检查库存
        if (coupon.getRemainingStock() <= 0) {
            log.warn("优惠券库存不足: {}", couponId);
            return false;
        }

        // 检查是否已领取
        QueryWrapper<UserCoupon> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId).eq("coupon_id", couponId);
        if (userCouponMapper.selectCount(wrapper) > 0) {
            log.warn("用户已领取该优惠券: userId={}, couponId={}", userId, couponId);
            return false;
        }

        // 创建用户优惠券记录
        UserCoupon userCoupon = new UserCoupon();
        userCoupon.setUserId(userId);
        userCoupon.setCouponId(couponId);
        userCoupon.setReceiveTime(LocalDateTime.now());
        userCoupon.setStatus(1); // 1-未使用

        // 减少库存
        coupon.setRemainingStock(coupon.getRemainingStock() - 1);

        try {
            // 保存用户优惠券记录
            userCouponMapper.insert(userCoupon);
            // 更新优惠券库存
            updateById(coupon);
            log.info("用户领取优惠券成功: userId={}, couponId={}", userId, couponId);
            return true;
        } catch (Exception e) {
            log.error("用户领取优惠券失败: userId={}, couponId={}", e);
            throw new RuntimeException("领取优惠券失败", e);
        }
    }

    @Override
    public List<UserCouponDTO> getUserCoupons(Long userId) {
        List<UserCoupon> userCoupons = userCouponMapper.selectUserAllCoupons(userId);
        return userCoupons.stream().map(this::convertToUserCouponDTO).collect(Collectors.toList());
    }

    @Override
    public List<UserCouponDTO> getUserAvailableCoupons(Long userId) {
        List<UserCoupon> userCoupons = userCouponMapper.selectUserAvailableCoupons(userId);
        return userCoupons.stream().map(this::convertToUserCouponDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean useCoupon(Long userId, Long userCouponId, Long orderId) {
        UserCoupon userCoupon = userCouponMapper.selectById(userCouponId);
        if (userCoupon == null || !userCoupon.getUserId().equals(userId)) {
            log.warn("用户优惠券不存在或权限不足: userId={}, userCouponId={}", userId, userCouponId);
            return false;
        }

        if (userCoupon.getStatus() != 1) {
            log.warn("优惠券状态不正确: status={}", userCoupon.getStatus());
            return false;
        }

        // 更新优惠券状态
        userCoupon.setStatus(2); // 2-已使用
        userCoupon.setUseTime(LocalDateTime.now());
        userCoupon.setOrderId(orderId);

        try {
            userCouponMapper.updateById(userCoupon);
            log.info("使用优惠券成功: userId={}, userCouponId={}, orderId={}", userId, userCouponId, orderId);
            return true;
        } catch (Exception e) {
            log.error("使用优惠券失败: userId={}, userCouponId={}", userId, userCouponId, e);
            throw new RuntimeException("使用优惠券失败", e);
        }
    }

    @Override
    public boolean isCouponAvailable(Long couponId) {
        Coupon coupon = getById(couponId);
        if (coupon == null) return false;

        LocalDateTime now = LocalDateTime.now();
        return coupon.getIsEnabled() == 1 &&
               coupon.getValidStartTime().isBefore(now) &&
               coupon.getValidEndTime().isAfter(now) &&
               coupon.getRemainingStock() > 0;
    }

    /**
     * 将Coupon转换为CouponDTO
     */
    private CouponDTO convertToDTO(Coupon coupon) {
        CouponDTO dto = BeanUtil.copyProperties(coupon, CouponDTO.class);

        // 设置券类型描述
        switch (coupon.getType()) {
            case 1:
                dto.setTypeDesc("满减券");
                break;
            case 2:
                dto.setTypeDesc("折扣券");
                break;
            case 3:
                dto.setTypeDesc("免费服务券");
                break;
            default:
                dto.setTypeDesc("未知类型");
        }

        // 设置优惠规则描述
        try {
            if (JSONUtil.isJson(coupon.getDiscountRule())) {
                var json = JSONUtil.parseObj(coupon.getDiscountRule());
                switch (coupon.getType()) {
                    case 1:
                        if (json.containsKey("min_amount") && json.containsKey("reduce")) {
                            dto.setDiscountDesc("满" + json.getInt("min_amount") + "减" + json.getInt("reduce"));
                        } else {
                            dto.setDiscountDesc("满减券");
                        }
                        break;
                    case 2:
                        if (json.containsKey("discount_rate")) {
                            double rate = json.getDouble("discount_rate");
                            dto.setDiscountDesc("享受" + (rate * 10) + "折优惠");
                        } else {
                            dto.setDiscountDesc("折扣券");
                        }
                        break;
                    case 3:
                        if (json.containsKey("service_id")) {
                            dto.setDiscountDesc("免费服务券");
                        } else {
                            dto.setDiscountDesc("免费服务券");
                        }
                        break;
                    default:
                        dto.setDiscountDesc("优惠券");
                }
            } else {
                dto.setDiscountDesc("优惠券");
            }
        } catch (Exception e) {
            log.warn("解析优惠券规则失败: couponId={}, discountRule={}", coupon.getId(), coupon.getDiscountRule(), e);
            dto.setDiscountDesc("优惠券");
        }

        // 设置是否可用
        LocalDateTime now = LocalDateTime.now();
        dto.setIsAvailable(coupon.getIsEnabled() == 1 &&
                          coupon.getValidStartTime().isBefore(now) &&
                          coupon.getValidEndTime().isAfter(now) &&
                          coupon.getRemainingStock() > 0);

        return dto;
    }

    /**
     * 将UserCoupon转换为UserCouponDTO
     */
    private UserCouponDTO convertToUserCouponDTO(UserCoupon userCoupon) {
        UserCouponDTO dto = BeanUtil.copyProperties(userCoupon, UserCouponDTO.class);

        // 设置状态描述
        switch (userCoupon.getStatus()) {
            case 1:
                dto.setStatusDesc("未使用");
                break;
            case 2:
                dto.setStatusDesc("已使用");
                break;
            case 3:
                dto.setStatusDesc("已过期");
                break;
            default:
                dto.setStatusDesc("未知状态");
        }

        // 设置是否可用
        dto.setIsAvailable(userCoupon.getStatus() == 1);

        // 获取优惠券信息
        Coupon coupon = getById(userCoupon.getCouponId());
        if (coupon != null) {
            dto.setCoupon(convertToDTO(coupon));
        }

        return dto;
    }
}
